#if 1

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct meminfo
{
        void *addr;
        size_t size;

        struct meminfo *prev;
        struct meminfo *next;
} MEM;

extern void memerror(void *);

MEM *mem=NULL;

void *debug_malloc(size_t size)
{
        MEM *pmem;
        void *ret;

        ret=malloc(size);

        if (ret == NULL)
                return NULL;

        if (mem == NULL)
        {
                pmem=mem=malloc(sizeof(*mem));
                memerror(mem);
                mem->prev=NULL;
        }
        else
        {
                pmem=mem;

                while (pmem != NULL)
                {
                        if (pmem->next == NULL)
                                break;

                        pmem=pmem->next;
                }

                pmem->next=malloc(sizeof(*pmem->next));
                memerror(pmem->next);
                pmem->next->prev=pmem;
                pmem=pmem->next;
        }

        pmem->addr=ret;
        pmem->size=size;
        pmem->next=NULL;

#if 0
        printf("===============\n");
        pmem=mem;
        while (pmem != NULL)
        {
                printf("Alocado: 0x%x\tTamanho: %ld\n",(unsigned int)pmem->addr,(long)pmem->size);

                pmem=pmem->next;
        }
        printf("===============\n");
#endif

        return ret;
}

void *debug_realloc(void *p, size_t size)
{
        MEM *pmem;
        void *ret;
        bool found=false;

        pmem=mem;

        while (pmem != NULL)
        {
                if (pmem->addr == p) /*Apaga*/
                {
                        if (mem == pmem)
                        {
                                mem=mem->next;
                                if (mem != NULL)
                                        mem->prev=NULL;
                        }
                        else
                        {
                                pmem->prev->next=pmem->next;
                                if (pmem->next != NULL)
                                        pmem->next->prev=pmem->prev;
                        }

                        free(pmem);
                        found=true;
                        break;
                }

                pmem=pmem->next;
        }

        if (!found)
                fprintf(stderr,"DEBUG realloc(): Endereço 0x%x não foi alocado\n",(unsigned int)p);

        ret=realloc(p,size);

        if (ret == NULL)
                return NULL;

        if (mem == NULL)
        {
                pmem=mem=malloc(sizeof(*mem));
                memerror(mem);
                mem->prev=NULL;
        }
        else
        {
                pmem=mem;

                while (pmem != NULL)
                {
                        if (pmem->next == NULL)
                                break;

                        pmem=pmem->next;
                }

                pmem->next=malloc(sizeof(*pmem->next));
                memerror(pmem->next);
                pmem->next->prev=pmem;
                pmem=pmem->next;
        }

        pmem->addr=ret;
        pmem->size=size;
        pmem->next=NULL;

        return ret;
}

void debug_free(void *p)
{
        MEM *pmem;
        bool found=false;

        if (p == NULL)
                return;

        pmem=mem;

        while (pmem != NULL)
        {
                if (pmem->addr == p) /*Apaga*/
                {
                        if (mem == pmem)
                        {
                                mem=mem->next;
                                if (mem != NULL)
                                        mem->prev=NULL;
                        }
                        else
                        {
                                pmem->prev->next=pmem->next;
                                if (pmem->next != NULL)
                                        pmem->next->prev=pmem->prev;
                        }

                        free(pmem);
                        found=true;
                        break;
                }

                pmem=pmem->next;
        }

        if (!found)
                fprintf(stderr,"DEBUG free(): Endereço 0x%x não foi alocado\n",(unsigned int)p);

        free(p);
}

void debug_fake_malloc(void *p)
{
        MEM *pmem;

        if (mem == NULL)
        {
                pmem=mem=malloc(sizeof(*mem));
                memerror(mem);
                mem->prev=NULL;
        }
        else
        {
                pmem=mem;

                while (pmem != NULL)
                {
                        if (pmem->next == NULL)
                                break;

                        pmem=pmem->next;
                }

                pmem->next=malloc(sizeof(*pmem->next));
                memerror(pmem->next);
                pmem->next->prev=pmem;
                pmem=pmem->next;
        }

        pmem->addr=p;
        pmem->size=0;
        pmem->next=NULL;
}

void debug_abort(int sig_num)
{
        exit(0);
}

#endif
